package admin

import (
	"html"

	"github.com/gin-gonic/gin"

	"github.com/super-team/start-kit/handler/response"
	"github.com/super-team/start-kit/middlewares/jwt"
	"github.com/super-team/start-kit/models"
	"github.com/super-team/start-kit/tools/log"
	"github.com/super-team/start-kit/tools/util"
)

func Route(r *gin.RouterGroup, middlewares ...gin.HandlerFunc) {

	a := r.Group("/admin", middlewares...)
	{
		a.DELETE("", deleteUser)
		a.POST("", addUser)
		a.PUT("", updateUser)
		a.GET("/list", getUserList)
		a.PUT("/status", updateUserStatus)
		a.PUT("/role", updateUserRole)
		a.PUT("/pwd", updatePassword)
	}

	aa := r.Group("", middlewares...)
	{
		aa.GET("/getInfo", getAdminInfo)
	}
}

// @Summary 获取个人信息
// @Description 获取个人信息
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 {string} string	"{"code": 200,"msg": "获取个人信息成功","data": ""}"
// @Failure 200 {string} string	"{"code": -1, "message": "用户不存在"}"
// @Router /api/getInfo [get]
func getAdminInfo(ctx *gin.Context) {
	user := jwt.GetAuthUser(ctx)
	role := jwt.GetAuthRole(ctx)
	if user == nil || role == nil {
		response.Error(ctx, "用户不存在")
		return
	}
	roles := []string{*role.RoleName}
	permissions := []string{"*:*:*"}
	buttons := []string{"*:*:*"}

	var mp = make(map[string]interface{})
	mp["roles"] = roles
	if roles[0] == "admin" || roles[0] == "系统管理员" {
		mp["permissions"] = permissions
		mp["buttons"] = buttons
	} else {
		list, err := models.GetRoleMenu(ctx, role.ID)
		if err != nil {
			log.Log.Err(err).Send()
			response.Error(ctx, "用户不存在")
			return
		}
		var l []string
		for _, i := range list {
			l = append(l, *i.Permission)
		}
		mp["permissions"] = l
		mp["buttons"] = l
	}
	mp["introduction"] = "am a super administrator"
	mp["avatar"] = "https://s1.ax1x.com/2020/11/10/BLmiE8.gif"
	mp["userName"] = user.Account
	mp["userId"] = user.ID
	mp["name"] = user.Name
	mp["role_id"] = user.RoleID
	response.Success(ctx, "获取个人信息成功", mp)
}

type deleteRequest struct {
	ID int64 `json:"id" binding:"required"`
}

// @Summary 删除用户
// @Description 删除用户
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body deleteRequest true "data"
// @Success 200 {string} string "{"code": 200, "data": null,"msg":"删除用户成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Router /api/admin [delete]
func deleteUser(ctx *gin.Context) {
	request := new(deleteRequest)
	if err := ctx.ShouldBindJSON(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	if response.ServerError(ctx, models.DeleteAdminByID(ctx, request.ID)) {
		return
	}
	response.Success(ctx, "删除用户成功", nil)
}

// @Summary 添加用户
// @Description 添加用户
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body models.Admin true "data"
// @Success 200 {string} string "{"code": 200, "data": null,"msg":"添加用户成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "网络异常，请稍后再试"}"
// @Router /api/admin [post]
func addUser(ctx *gin.Context) {
	request := new(models.AdminModel)
	if err := ctx.ShouldBindJSON(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	if request.Password == nil {
		response.Error(ctx, "请输入密码")
		return
	}
	if request.ID != 0 {
		response.Error(ctx, "参数错误")
		return
	}
	if !util.ValidatePhone(*request.Phone) {
		response.Error(ctx, "请输入正确的电话号码")
		return
	}
	exist, err := models.GetAdminByAccount(ctx, *request.Account)
	if response.ServerError(ctx, err) {
		return
	}
	if exist.ID != 0 {
		response.Error(ctx, "该账号已存在，请换一个")
		return
	}
	if response.ServerError(ctx, request.AddAdmin(ctx)) {
		return
	}
	response.Success(ctx, "添加用户成功", nil)
}

// @Summary 修改用户
// @Description 修改用户
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body models.AdminModel true "data"
// @Success 200 {string} string "{"code": 200, "data": null,"msg":"修改用户成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "网络异常，请稍后再试"}"
// @Router /api/admin [put]
func updateUser(ctx *gin.Context) {
	request := new(models.AdminModel)
	if err := ctx.ShouldBindJSON(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	if request.ID == 0 {
		response.Error(ctx, "参数错误")
		return
	}
	exist, err := models.GetAdminByAccount(ctx, *request.Account)
	if response.ServerError(ctx, err) {
		return
	}
	if exist.ID != request.ID {
		response.Error(ctx, "该账号已存在，请换一个")
		return
	}
	if !util.ValidatePhone(*request.Phone) {
		response.Error(ctx, "请输入正确的电话号码")
		return
	}
	request.Account = nil
	if response.ServerError(ctx, request.UpdateAdmin(ctx)) {
		return
	}
	response.Success(ctx, "修改用户成功", nil)
}

type updateStatusRequest struct {
	ID     int64 `json:"id"`
	Status int64 `json:"status"`
}

// @Summary 修改用户状态
// @Description 修改用户状态
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body updateStatusRequest true "data"
// @Success 200 {string} string "{"code": 200, "msg": "修改成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Router /api/admin/status [put]
func updateUserStatus(ctx *gin.Context) {
	request := new(updateStatusRequest)
	if err := ctx.ShouldBindJSON(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	s := int(request.Status)
	a := &models.AdminModel{
		Model:  models.Model{ID: uint64(request.ID)},
		Status: &s,
	}
	if response.ServerError(ctx, a.UpdateAdminStatus(ctx)) {
		return
	}
	response.Success(ctx, "修改成功", nil)
}

type updatePwdRequest struct {
	Old string `json:"old" form:"old" binding:"required"`
	New string `json:"new" form:"new" binding:"required"`
}

// @Summary 修改密码
// @Description 修改密码
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body updatePwdRequest true "data"
// @Success 200 {string} string "{"code": 200, "msg": "修改成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Router /api/admin/pwd [put]
func updatePassword(ctx *gin.Context) {
	request := new(updatePwdRequest)
	if err := ctx.ShouldBind(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	user := jwt.GetAuthUser(ctx)
	if user == nil {
		response.Error(ctx, "参数错误")
		return
	}
	if !util.PasswordVerify(request.Old, *user.Password) {
		response.Error(ctx, "旧密码错误")
		return
	}
	p, err := util.PasswordHash(request.New)
	if err != nil {
		response.Error(ctx, response.ErrServer.Error())
		return
	}
	a := &models.AdminModel{
		Model:    models.Model{ID: user.ID},
		Password: &p,
	}
	if response.ServerError(ctx, a.UpdateAdminPwd(ctx)) {
		return
	}
	response.Success(ctx, "修改密码成功", nil)
}

type listRequest struct {
	PageSize  int     `json:"pageSize" form:"pageSize"`
	PageIndex int     `json:"pageIndex" form:"pageIndex"`
	Search    *string `json:"search" form:"search"`
	Status    *int    `json:"status" form:"status"`
}

// @Summary 获取用户列表
// @Description 获取用户列表
// @Tags admin
// @Param Authorization header string false "Bearer 用户令牌"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Param search query string false "搜索字段"
// @Param status query int false "状态"
// @Success 200 {string} string "{"code": 200, "data": [...]}"
// @Failure 200 {string} string	"{"code": -1, "message": "参数错误"}"
// @Router /api/admin/list [get]
func getUserList(ctx *gin.Context) {
	request := new(listRequest)
	if err := ctx.ShouldBindQuery(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	if request.PageSize == 0 {
		request.PageSize = 10
	}
	if request.PageIndex == 0 {
		request.PageIndex = 1
	}
	if request.Search != nil {
		*request.Search = html.EscapeString(*request.Search)
	}
	list, err := models.GetUserList(ctx, request.PageIndex, request.PageSize, request.Search, request.Status)
	if response.ServerError(ctx, err) {
		return
	}
	response.Success(ctx, "获取用户列表成功", list)
}

type updateRoleRequest struct {
	ID     int64 `json:"id"`
	RoleId int64 `json:"role_id"`
}

// @Summary 修改用户角色
// @Description 修改用户角色
// @Tags admin
// @Accept json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param data body updateRoleRequest true "data"
// @Success 200 {string} string "{"code": 200, "msg": "修改成功"}"
// @Failure 200 {string} string	"{"code": -1, "msg": "参数错误"}"
// @Router /api/admin/role [put]
func updateUserRole(ctx *gin.Context) {
	request := new(updateRoleRequest)
	if err := ctx.ShouldBindJSON(request); err != nil {
		response.Error(ctx, "参数错误")
		return
	}
	user, err := models.GetAdminByID(ctx, request.ID)
	if response.ServerError(ctx, err) {
		return
	}
	if user.ID == 0 {
		response.Error(ctx, "参数错误")
		return
	}
	if int64(*user.RoleID) == request.RoleId {
		response.Success(ctx, "修改成功", nil)
	}
	if response.ServerError(ctx, models.UpdateAdminRole(ctx, request.ID, request.RoleId)) {
		return
	}
	response.Success(ctx, "修改成功", nil)
}
